/*******************************************************************************
 * @brief: my micro
 * @Author:   aple
 * @Date: 2022-11-17 09:48:54
 * @LastEditors: aple
 * @LastEditTime: 2022-11-17 10:31:58
 * @Verision: 1.0.0.0
 ******************************************************************************/
#ifndef _MY_MICRO_FUN_H_
#define _MY_MICRO_FUN_H_

#include "mytype.h"

#ifdef __cplusplus
extern "C"
{
#endif

/*****************************************************************************
 * @brief 指定结构体成员相对于首地址的偏移量
 *****************************************************************************/
#define str_member_offset(str_type, member) ((uu32)(&((str_type *)0)->member))
#ifndef member_offset
#define member_offset(str_type, member) ((uu32)(&((str_type *)0)->member))
#endif

/*****************************************************************************
 * @brief 结构转换数组的成员索引，要求结构成员类型统一
 *****************************************************************************/
#define str16_member_pos(str_type, member) (str_member_offset(str_type, member) / 2)
#define str32_member_pos(str_type, member) (str_member_offset(str_type, member) / 4)
#define str64_member_pos(str_type, member) (str_member_offset(str_type, member) / 8)

#define member16_pos str16_member_pos
#define member32_pos str32_member_pos
#define member64_pos str64_member_pos

/*****************************************************************************
 * @brief   地址a是否边界对齐于x
 *****************************************************************************/
#define is_align(a, x) ((0 == ((UU32)(a)) & ((x) - 1)) ? 1 : 0)

/*****************************************************************************
 * @brief   cortex-m bitband
 *****************************************************************************/
#define CORTEXM_BITBAND_ADDR(addr, bitnum) \
	(((uu32)(addr) & 0xF0000000) + 0x2000000 + (((uu32)(addr) & 0xFFFFF) << 5) + ((bitnum) << 2))

#define CORTEXM_BITBAND_REG(reg, bitnum) \
	(((uu32)(&(reg)) & 0xF0000000) + 0x2000000 + (((uu32)(&(reg)) & 0xFFFFF) << 5) + ((bitnum) << 2))

#define cortexm_bitband_addr CORTEXM_BITBAND_ADDR
#define cortexm_bitband_REG CORTEXM_BITBAND_REG

/*****************************************************************************
 * @brief   比较
 *****************************************************************************/
#if !defined(ext_max)
#define ext_max(a, b) (((a) > (b)) ? (a) : (b))
#define ext_min(a, b) (((a) < (b)) ? (a) : (b))
#define ext_max3(a, b, c) ext_max(ext_max(a, b), c)
#define ext_min3(a, b, c) ext_min(ext_min(a, b), c)
#define ext_max4(a, b, c, d) ext_max(ext_max(a, b), ext_max(c, d))
#define ext_min4(a, b, c, d) ext_min(ext_min(a, b), ext_min(c, d))
#endif

#if !defined(MAX)
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif

#define ext_abs(x) (((x) < 0) ? (-(x)) : (x))

/*****************************************************************************
 * @brief   交换
 *****************************************************************************/
#define swap32(ap, bp)  \
	do                  \
	{                   \
		UU32 temp = ap; \
		ap = bp;        \
		bp = temp;      \
	} while (0)

#define swap_f32(ap, bp) \
	do                   \
	{                    \
		float temp = ap; \
		ap = bp;         \
		bp = temp;       \
	} while (0)

#define swap16(ap, bp)  \
	do                  \
	{                   \
		UU16 temp = ap; \
		ap = bp;        \
		bp = temp;      \
	} while (0)

#define swap08(ap, bp) \
	do                 \
	{                  \
		UU8 temp = ap; \
		ap = bp;       \
		bp = temp;     \
	} while (0)

/*****************************************************************************
 * @brief   时间转换
 *****************************************************************************/
#define bin_tim_split(mm) (((mm) / 60) * 100 + (mm) % 60)  // 以60为基数分割为两部分
#define bin_tim_merge(hm) (((hm) / 100) * 60 + (hm) % 100) // 以60为基数合并

/*****************************************************************************
 * @brief   符号扩展：将x位(含符号位)有符号数扩展为32/16位有符号数。
 *****************************************************************************/
#define ix_to_i32(var, x)                                                     \
	((uu32)var & ((uu32)1 << ((x) - 1)))                                      \
		? (((uu32)var & ~((UINT32_MAX >> (x)) << (x))) | (UINT32_MAX << (x))) \
		: ((uu32)var & ~((UINT32_MAX >> (x)) << (x)))

#define ix_to_i16(var, x)                                                     \
	((uu16)var & ((uu16)1 << ((x) - 1)))                                      \
		? (((uu16)var & ~((UINT16_MAX >> (x)) << (x))) | (UINT16_MAX << (x))) \
		: ((uu16)var & ~((UINT16_MAX >> (x)) << (x)))

/*****************************************************************************
 * @brief   循环移位
 *****************************************************************************/
#define ror08(word, shift) \
	((((uu08)(word)) >> ((uwcpu)(shift) & 0x07)) | (((uu08)(word)) << ((-(uwcpu)(shift)) & 0x07)))

#define rol08(word, shift) \
	((((uu08)(word)) << ((uwcpu)(shift) & 0x07)) | (((uu08)(word)) >> ((-(uwcpu)(shift)) & 0x07)))

#define ror16(word, shift) \
	((((uu16)(word)) >> ((uwcpu)(shift) & 0x0F)) | (((uu16)(word)) << ((-(uwcpu)(shift)) & 0x0F)))

#define rol16(word, shift) \
	((((uu16)(word)) << ((uwcpu)(shift) & 0x0F)) | (((uu16)(word)) >> ((-(uwcpu)(shift)) & 0x0F)))

#define ror32(word, shift) \
	((((uu32)(word)) >> ((uwcpu)(shift) & 0x1F)) | (((uu32)(word)) << ((-(uwcpu)(shift)) & 0x1F)))

#define rol32(word, shift) \
	((((uu32)(word)) << ((uwcpu)(shift) & 0x1F)) | (((uu32)(word)) >> ((-(uwcpu)(shift)) & 0x1F)))

#define ror64(word, shift) \
	((((uu64)(word)) >> ((uwcpu)(shift) & 0x3F)) | (((uu64)(word)) << ((-(uwcpu)(shift)) & 0x3F)))

#define rol64(word, shift) \
	((((uu64)(word)) << ((uwcpu)(shift) & 0x3F)) | (((uu64)(word)) >> ((-(uwcpu)(shift)) & 0x3F)))

/*****************************************************************************
 * @brief   掩蔽位值定义
 *****************************************************************************/
#ifndef _BIT_Msk
#define _BIT_Msk(x) (1UL << (x))
#endif

#ifndef _BIT
#define _BIT _BIT_Msk
#endif

#ifndef _NBIT
#define _NBIT(x) (~_BIT_Msk(x))
#endif

#ifndef _BITS_Msk
#define _BITS_Msk(m, n) (((m) > (n)) ? ((UINT32_MAX >> (31 - (m))) & (UINT32_MAX << (n))) : ((UINT32_MAX >> (31 - (n))) & (UINT32_MAX << (m))))
#endif

#ifndef _BITS
#define _BITS _BITS_Msk
#endif

#ifndef _NBITS
#define _NBITS(m, n) (~_BITS_Msk(m, n))
#endif

/*****************************************************************************
 * @brief   位处理
 *****************************************************************************/
#ifndef SetBit
#define SetBit(var, pos) ((var) |= (1ul << (pos)))
#define ClrBit(var, pos) ((var) &= ~(1ul << (pos)))
#define TogBit(var, pos) ((var) ^= (1ul << (pos)))
#define GetBit(var, pos) (((var) >> (pos)) & 1ul)
#define SetBitVal(var, pos, val) ((val) & 1U) ? (SetBit(var, pos)) : (ClrBit(var, pos))
#endif

#ifndef set_bit
#define set_bit(var, pos) ((var) |= (1ul << (pos)))
#define clr_bit(var, pos) ((var) &= ~(1ul << (pos)))
#define tog_bit(var, pos) ((var) ^= (1ul << (pos)))
#define get_bit(var, pos) (((var) >> (pos)) & 1ul)
#define set_bit_val(var, pos, val) ((val) & 1U) ? (set_bit(var, pos)) : (clr_bit(var, pos))
#endif

#ifndef bit_set
#define bit_set(var, pos) ((var) |= (1ul << (pos)))
#define bit_clr(var, pos) ((var) &= ~(1ul << (pos)))
#define bit_tog(var, pos) ((var) ^= (1ul << (pos)))
#define bit_get(var, pos) (((var) >> (pos)) & 1ul)
#define bit_set_val(var, pos, val) ((val) & 1U) ? (bit_set(var, pos)) : (bit_clr(var, pos))
#endif

#define set_nbit(var, pos) ((var) &= ~(1ul << (pos)))
#define clr_nbit(var, pos) ((var) |= (1ul << (pos)))
#define nbit_set set_nbit
#define nbit_clr clr_nbit

/*****************************************************************************
 * @brief   多位操作
 *****************************************************************************/
#ifndef set_bits
#define set_bits(val, m, n) (val |= _BITS_Msk(m, n))
#define clr_bits(val, m, n) (val &= ~_BITS_Msk(m, n))
#define tog_bits(val, m, n) (val ^= _BITS_Msk(m, n))
#define get_bits(val, m, n) (((m) > (n)) ? (((val) & _BITS_Msk(m, n)) >> (n)) : (((val) & _BITS_Msk(m, n)) >> (m)))
#define set_bits_val(var, m, n, val) var = (var & (~_BITS_Msk(m, n))) | (get_bits(val, 0, (((m) > (n)) ? ((m) - (n)) : ((n) - (m)))) << (((m) > (n)) ? (n) : (m)))
#endif

#ifndef bits_set
#define bits_set set_bits
#define bits_clr clr_bits
#define bits_tog tog_bits
#define bits_get get_bits
#define bits_set_val set_bits_val
#endif

/*****************************************************************************
 * @brief   位比较
 *****************************************************************************/
#define comp_bit(v1, v2, pos) ((((v1) ^ (v2)) >> (pos)) & 1U)

/*****************************************************************************
 * @brief   根据位数生成输出值。0代表无输出。
 *****************************************************************************/
#ifndef U08_OBITS
#define U08_OBITS(x) ((uint8_t)(UINT8_MAX >> (8 - (x))))
#endif

#ifndef U16_OBITS
#define U16_OBITS(x) ((uint16_t)(UINT16_MAX >> (16 - (x))))
#endif

#ifndef U32_OBITS
#define U32_OBITS(x) ((uint32_t)(UINT32_MAX >> (32 - (x))))
#endif

/*****************************************************************************
 * @brief   掩蔽位处理
 *****************************************************************************/
#ifndef set_mask
#define set_mask(var, mask) var = (var) | (mask)
#define clr_mask(var, mask) var = (var) & (~(mask))
#define get_mask(var, mask) ((var) & (mask))
#define cset_mask(var, clr, set) var = (((var) & (~(clr))) | (set))
#endif

#ifndef mask_set
#define mask_set set_mask
#define mask_clr clr_mask
#define mask_get get_mask
#define mask_cset cset_mask
#endif

/*****************************************************************************
 * @brief   位图内位操作
 * @param pmap 首数据指针
 * @param pos  被操作bit位置
 * @param val  目标值
 *****************************************************************************/
#define map_bit_set(pmap, pos) bit_set(((uu8 *)(pmap))[(pos) >> 3], (pos) & 7U)
#define map_bit_clr(pmap, pos) bit_clr(((uu8 *)(pmap))[(pos) >> 3], (pos) & 7U)
#define map_bit_tog(pmap, pos) bit_tog(((uu8 *)(pmap))[(pos) >> 3], (pos) & 7U)
#define map_bit_get(pmap, pos) bit_get(((uu8 *)(pmap))[(pos) >> 3], (pos) & 7U)
#define map_bit_set_val(pmap, pos, val) bit_set_val(((uu8 *)(pmap))[(pos) >> 3], (pos) & 7U, val)

/*****************************************************************************
 * @brief   m n 必须在同一字段内（32bit字段），指针位置必须字对齐
 * @param pmap 首数据指针
 * @param m n  操作起始和结束位 \p pmap[m:n]\pmap[n:m]
 * @param val  目标值
 *****************************************************************************/
#define map_bits_set(pmap, m, n) bits_set(((uu32 *)(pmap))[(m) >> 5], (m) & 0x1FU, (n) & 0x1FU)
#define map_bits_clr(pmap, m, n) bits_clr(((uu32 *)(pmap))[(m) >> 5], (m) & 0x1FU, (n) & 0x1FU)
#define map_bits_tog(pmap, m, n) bits_tog(((uu32 *)(pmap))[(m) >> 5], (m) & 0x1FU, (n) & 0x1FU)
#define map_bits_get(pmap, m, n) bits_get(((uu32 *)(pmap))[(m) >> 5], (m) & 0x1FU, (n) & 0x1FU)
#define map_bits_set_val(pmap, m, n, val) bits_set_val(((uu32 *)(pmap))[(m) >> 5], (m) & 0x1FU, (n) & 0x1FU, val)

/*****************************************************************************
 * @brief   分组位处理-单变量
 * @param var  变量名
 * @param gp   被操作bit组
 * @param val  目标值
 *****************************************************************************/
#define group_bits1_set(var, gp, val) cset_mask(var, (0x01UL << (gp) * 1), ((val) << (gp) * 1))
#define group_bits2_set(var, gp, val) cset_mask(var, (0x03UL << (gp) * 2), ((val) << (gp) * 2))
#define group_bits3_set(var, gp, val) cset_mask(var, (0x07UL << (gp) * 3), ((val) << (gp) * 3))
#define group_bits4_set(var, gp, val) cset_mask(var, (0x0FUL << (gp) * 4), ((val) << (gp) * 4))
#define group_bits1_clr(var, gp) clr_mask(var, (0x01UL << (gp) * 1))
#define group_bits2_clr(var, gp) clr_mask(var, (0x03UL << (gp) * 2))
#define group_bits3_clr(var, gp) clr_mask(var, (0x07UL << (gp) * 3))
#define group_bits4_clr(var, gp) clr_mask(var, (0x0FUL << (gp) * 4))

/*****************************************************************************
 * @brief   分组位处理-以变量地址为首地址的数组
 * @param var  变量名
 * @param gp   被操作bit组
 * @param val  目标值
 *****************************************************************************/
#define multi32_bits1_set(var, gp, val) cset_mask(vu32p(&var)[(gp) >> 5], ((uu32)0x01U << ((gp) & 0x1F) * 1), ((val) << ((gp) & 0x1F) * 1))
#define multi32_bits2_set(var, gp, val) cset_mask(vu32p(&var)[(gp) >> 4], ((uu32)0x03U << ((gp) & 0x0F) * 2), ((val) << ((gp) & 0x0F) * 2))
#define multi32_bits3_set(var, gp, val) cset_mask(vu32p(&var)[(gp) / 10], ((uu32)0x07U << ((gp) % 10) * 3), ((val) << ((gp) % 10) * 3))
#define multi32_bits4_set(var, gp, val) cset_mask(vu32p(&var)[(gp) >> 3], ((uu32)0x0FU << ((gp) & 0x07) * 4), ((val) << ((gp) & 0x07) * 4))
#define multi32_bits5_set(var, gp, val) cset_mask(vu32p(&var)[(gp) / 6], ((uu32)0x1FU << ((gp) % 6) * 5), ((val) << ((gp) % 6) * 5))

#define multi16_bits1_set(var, gp, val) cset_mask(vu16p(&var)[(gp) >> 4], ((uu16)0x01U << ((gp) & 0x0F) * 1), ((val) << ((gp) & 0x0F) * 1))
#define multi16_bits2_set(var, gp, val) cset_mask(vu16p(&var)[(gp) >> 3], ((uu16)0x03U << ((gp) & 0x07) * 2), ((val) << ((gp) & 0x07) * 2))
#define multi16_bits4_set(var, gp, val) cset_mask(vu16p(&var)[(gp) >> 2], ((uu16)0x0FU << ((gp) & 0x03) * 4), ((val) << ((gp) & 0x03) * 4))

#define multi8_bits1_set(var, gp, val) cset_mask(vu8p(&var)[(gp) >> 3], ((uu8)0x01U << ((gp) & 0x07) * 1), ((val) << ((gp) & 0x07) * 1))
#define multi8_bits2_set(var, gp, val) cset_mask(vu8p(&var)[(gp) >> 2], ((uu8)0x03U << ((gp) & 0x03) * 2), ((val) << ((gp) & 0x03) * 2))
#define multi8_bits4_set(var, gp, val) cset_mask(vu8p(&var)[(gp) >> 1], ((uu8)0x0FU << ((gp) & 0x01) * 4), ((val) << ((gp) & 0x01) * 4))

/*****************************************************************************
 * @brief   数据位段修改, 小端索引 pos的0代表最低位
 * var bits[vpos...] = dat bits[dpos...]，位长度blen
 *****************************************************************************/
#define u8_lbit_seg_set(var, vpos, dat, dpos, blen)                                 \
	do                                                                              \
	{                                                                               \
		uu8 mask = (U8_MAX << vpos) & (U8_MAX >> (8 - (vpos + blen)));              \
		var = (vpos >= dpos) ? ((var & (~mask)) | ((dat << (vpos - dpos)) & mask))  \
							 : ((var & (~mask)) | ((dat >> (dpos - vpos)) & mask)); \
	} while (0)

#define u16_lbit_seg_set(var, vpos, dat, dpos, blen)                                \
	do                                                                              \
	{                                                                               \
		uu16 mask = (U16_MAX << vpos) & (U16_MAX >> (16 - (vpos + blen)));          \
		var = (vpos >= dpos) ? ((var & (~mask)) | ((dat << (vpos - dpos)) & mask))  \
							 : ((var & (~mask)) | ((dat >> (dpos - vpos)) & mask)); \
	} while (0)

#define u32_lbit_seg_set(var, vpos, dat, dpos, blen)                                \
	do                                                                              \
	{                                                                               \
		uu32 mask = (U32_MAX << vpos) & (U32_MAX >> (32 - (vpos + blen)));          \
		var = (vpos >= dpos) ? ((var & (~mask)) | ((dat << (vpos - dpos)) & mask))  \
							 : ((var & (~mask)) | ((dat >> (dpos - vpos)) & mask)); \
	} while (0)

/*****************************************************************************
 * @brief   数据位段修改, 大端索引 pos的0代表最高位
 * var bits[vpos...] = dat bits[dpos...]，位长度blen
 *****************************************************************************/
#define u8_bbit_seg_set(var, vpos, dat, dpos, blen)                                 \
	do                                                                              \
	{                                                                               \
		uu8 mask = (U8_MAX >> vpos) & (U8_MAX << (8 - (vpos + blen)));              \
		var = (vpos >= dpos) ? ((var & (~mask)) | ((dat >> (vpos - dpos)) & mask))  \
							 : ((var & (~mask)) | ((dat << (dpos - vpos)) & mask)); \
	} while (0)

#define u16_bbit_seg_set(var, vpos, dat, dpos, blen)                                \
	do                                                                              \
	{                                                                               \
		uu16 mask = (U16_MAX >> vpos) & (U16_MAX << (16 - (vpos + blen)));          \
		var = (vpos >= dpos) ? ((var & (~mask)) | ((dat >> (vpos - dpos)) & mask))  \
							 : ((var & (~mask)) | ((dat << (dpos - vpos)) & mask)); \
	} while (0)

#define u32_bbit_seg_set(var, vpos, dat, dpos, blen)                                \
	do                                                                              \
	{                                                                               \
		uu32 mask = (U32_MAX >> vpos) & (U32_MAX << (32 - (vpos + blen)));          \
		var = (vpos >= dpos) ? ((var & (~mask)) | ((dat >> (vpos - dpos)) & mask))  \
							 : ((var & (~mask)) | ((dat << (dpos - vpos)) & mask)); \
	} while (0)

/*****************************************************************************
 * @brief   数值范围检测
 *****************************************************************************/
#define rang_offset(val, set, offset) ((((val) + (offset)) >= (set)) && ((val) <= ((set) + (offset))))
#define rang_check(val, min, max) (((val) >= (min)) && ((val) <= (max)))
#define rang_limit(val, min, max) \
	do                            \
	{                             \
		if (val < (min))          \
			val = (min);          \
		else if (val > (max))     \
			val = (max);          \
	} while (0)

#define rang_limit_low(val, min) \
	do                           \
	{                            \
		if (val < (min))         \
			val = (min);         \
	} while (0)

#define rang_limit_high(val, max) \
	do                            \
	{                             \
		if (val > (max))          \
			val = (max);          \
	} while (0)

/*****************************************************************************
 * @brief   杂项
 *****************************************************************************/
// array length get
#define array_len(x) (sizeof(x) / sizeof(x[0]))
#define array_size array_len
#define arr_len array_len
#define arr_size array_len

// ascii check
#define asc_dec_check(ch) (((ch) >= '0') && ((ch) <= '9'))
#define asc_oct_check(ch) (((ch) >= '0') && ((ch) <= '7'))
#define asc_hex_check(ch) (asc_dec_check(ch) || (((ch) >= 'A') && ((ch) <= 'F')) || (((ch) >= 'a') && ((ch) <= 'f')))

// loop
#define loop(x) for (int index = 0; index < (int)(x); index++)
#define loop_i(x) for (index = 0; index < (int)(x); index++)

#define each(array) for (int index = 0; index < sizeof(array) / sizeof(array[0]); index++)
#define each_i(array) for (index = 0; index < sizeof(array) / sizeof(array[0]); index++)

// 数据映射 (a,b)=>(m,n)
#define dat_remap(a, b, m, n, dat) ((m) + ((dat) - (a)) * ((n) - (m)) / ((b) - (a)))

/*****************************************************************************
 * @brief   简单计算
 *****************************************************************************/
#define var_loop_inc(var, min, max) \
	do                              \
	{                               \
		if (var >= (max))           \
			var = (min);            \
		else                        \
			var++;                  \
	} while (0)

#define var_loop_dec(var, min, max) \
	do                              \
	{                               \
		if (var <= (min))           \
			var = (max);            \
		else                        \
			var--;                  \
	} while (0)

#define var_limit_inc(var, max) \
	do                          \
	{                           \
		if (var >= (max))       \
			var = (max);        \
		else                    \
			var++;              \
	} while (0)

#define var_limit_dec(var, min) \
	do                          \
	{                           \
		if (var <= (min))       \
			var = (min);        \
		else                    \
			var--;              \
	} while (0)

// 变量最大值
#define IMAX(x) ((1UL << (sizeof(x) * 8 - 1)) - 1)
#define UMAX(x) ((UINT32_MAX >> (32 - sizeof(x) * 8)))

// 有符号变量递增至最大值
#define var_inc_to_imax(x) \
	do                     \
	{                      \
		if (x < IMAX(x))   \
			x++;           \
	} while (0)

// 变量递增至最大值
#define var_inc_to_umax(x) \
	do                     \
	{                      \
		if (x < UMAX(x))   \
			x++;           \
	} while (0)

// 有效值加载并清除原变量
#define var_active_load(src, des) \
	do                            \
	{                             \
		if (src)                  \
		{                         \
			src = 0;              \
			des = 1;              \
		}                         \
	} while (0)

/*****************************************************************************
 * @brief   缓存操作，缓存名为buff, 缓存索引长度为index
 *****************************************************************************/
// 缓存当前位置填充数据, 数量n
#define buff_fill_dat(dat, n)    \
	do                           \
	{                            \
		int _fill_cnt;           \
		_fill_cnt = (n);         \
		while (_fill_cnt--)      \
			buff[index++] = dat; \
	} while (0)

// 缓存当前添加数据，长度为n
#define buff_add_dat(dats, n)                    \
	do                                           \
	{                                            \
		int _fill_cnt;                           \
		const u08 *__dats = (const u08 *)(dats); \
		_fill_cnt = (n);                         \
		while (_fill_cnt--)                      \
			buff[index++] = *__dats++;           \
	} while (0)

// 缓存当前添加字符串，缓存长度len
#define buff_add_str(str, len)                  \
	do                                          \
	{                                           \
		const u08 *__dats = (const u08 *)(str); \
		while (*__dats && index < (len))        \
			buff[index++] = *__dats++;          \
	} while (0)

// 缓存当前添加字符
#define buff_add_ch(ch) buff[index++] = ch

/*****************************************************************************
 * @brief  memory data
 *****************************************************************************/
#ifndef outpw
#define outpw(port, value) *((vuu32 *)(port)) = value
#define inpw(port) (*((vuu32 *)(port)))
#define outps(port, value) *((vuu16 *)(port)) = value
#define inps(port) (*((vuu16 *)(port)))
#define outpb(port, value) *((vuu08 *)(port)) = value
#define inpb(port) (*((vuu08 *)(port)))
#define outp32(port, value) *((vuu32 *)(port)) = value
#define inp32(port) (*((vuu32 *)(port)))
#define outp16(port, value) *((vuu16 *)(port)) = value
#define inp16(port) (*((vuu16 *)(port)))
#define outp8(port, value) *((vuu08 *)(port)) = value
#define inp8(port) (*((vuu08 *)(port)))
#endif

#define inpf32(port) (*((volatile float *)(port)))
#define outpf32(port, value) *((volatile float *)(port)) = value
#define inpf64(port) (*((volatile double *)(port)))
#define outfd64(port, value) *((volatile double *)(port)) = value
#define inp64(port) (*((vuu64 *)(port)))
#define outp64(port, value) *((vuu64 *)(port)) = value

#define ext_mem64(port) (*((vuu64 *)(port)))
#define ext_mem32(port) (*((vuu32 *)(port)))
#define ext_mem16(port) (*((vuu16 *)(port)))
#define ext_mem8(port) (*((vuu08 *)(port)))

#define ext_memi64(port) (*((vii64 *)(port)))
#define ext_memi32(port) (*((vii32 *)(port)))
#define ext_memi16(port) (*((vii16 *)(port)))
#define ext_memi8(port) (*((vii08 *)(port)))

#define ext_mem32f(port) (*((volatile float *)(port)))
#define ext_mem64f(port) (*((volatile double *)(port)))

#ifndef mem32
#define mem64 ext_mem64
#define mem32 ext_mem32
#define mem16 ext_mem16
#define mem8 ext_mem8

#define memi64 ext_memi64
#define memi32 ext_memi32
#define memi16 ext_memi16
#define memi8 ext_memi8

#define mem32f ext_mem32f
#define mem64f ext_mem64f
#endif

#define _MEM64(port) (*((uu64 *)(port)))
#define _MEM64F(port) (*((double *)(port)))
#define _MEM32(port) (*((uu32 *)(port)))
#define _MEM32F(port) (*((float *)(port)))
#define _MEM16(port) (*((uu16 *)(port)))
#define _MEM8(port) (*((uu08 *)(port)))

#define _VMEM64(port) (*((vuu64 *)(port)))
#define _VMEM64F(port) (*((volatile double *)(port)))
#define _VMEM32(port) (*((vuu32 *)(port)))
#define _VMEM32F(port) (*((volatile float *)(port)))
#define _VMEM16(port) (*((vuu16 *)(port)))
#define _VMEM8(port) (*((vuu08 *)(port)))

/*****************************************************************************
 * @brief   数据拷贝, len 指示 数据尺寸，均以 byte 为单位
 *****************************************************************************/
#define micro_dat08_copy(r, d, len) \
	do                              \
	{                               \
		uu32 cnt;                   \
		vuu08 *src, *des;           \
		cnt = len;                  \
		src = (vuu08 *)(r);         \
		des = (vuu08 *)(d);         \
		while (cnt--)               \
			*des++ = *src++;        \
	} while (0)

#define micro_dat16_copy(r, d, len) \
	do                              \
	{                               \
		uu32 cnt;                   \
		vuu16 *src, *des;           \
		cnt = (len) >> 1;           \
		src = (vuu16 *)(r);         \
		des = (vuu16 *)(d);         \
		while (cnt--)               \
			*des++ = *src++;        \
	} while (0)

#define micro_dat32_copy(r, d, len) \
	do                              \
	{                               \
		uu32 cnt;                   \
		vuu32 *src, *des;           \
		cnt = (len) >> 2;           \
		src = (vuu32 *)(r);         \
		des = (vuu32 *)(d);         \
		while (cnt--)               \
			*des++ = *src++;        \
	} while (0)

/*****************************************************************************
 * @brief   数据设置, len 指示 数据尺寸，均以 byte 为单位
 *****************************************************************************/
#define micro_dat08_set(ptr, dat, len) \
	do                                 \
	{                                  \
		uu32 cnt;                      \
		vuu08 *des;                    \
		cnt = len;                     \
		des = (vuu08 *)(ptr);          \
		while (cnt--)                  \
			*des++ = dat;              \
	} while (0)

#define micro_dat16_set(ptr, dat, len) \
	do                                 \
	{                                  \
		uu32 cnt;                      \
		vuu16 *des;                    \
		cnt = len;                     \
		des = (vuu16 *)(ptr);          \
		while (cnt--)                  \
			*des++ = dat;              \
	} while (0)

#define micro_dat32_set(rptr, dat, len) \
	do                                  \
	{                                   \
		uu32 cnt;                       \
		vuu32 *des;                     \
		cnt = len;                      \
		des = (vuu32 *)(ptr);           \
		while (cnt--)                   \
			*des++ = dat;               \
	} while (0)

/*****************************************************************************
 * @brief   数据合并分离
 *****************************************************************************/
#define byte_lb(x) ((x) & 0xFF)
#define byte_hb(x) (((x) >> 8) & 0xFF)
#define byte_ub(x) (((x) >> 16) & 0xFF)
#define byte_mb(x) (((x) >> 24) & 0xFF)

#define word_lw(x) ((x) & 0xFFFF)
#define word_hw(x) (((x) >> 16) & 0xFFFF)

#define word_make(hb, lb) ((UU16)((UU8)(lb) | ((UU8)(hb) << 8)))
#define dword_make(hw, lw) ((UU32)((UU16)(lw) | ((UU16)(hw) << 16)))
#define dword_wmake(hw, lw) ((UU32)((UU16)(lw) | ((UU16)(hw) << 16)))
#define dword_bmake(mb, ub, hb, lb) ((UU32)(((UU8)(mb) << 24) | ((UU8)(ub) << 16) | ((UU8)(hb) << 8) | ((UU8)(lb) << 0)))

	/*****************************************************************************
	 * @brief   基础状态
	 *****************************************************************************/
	typedef struct
	{
		uu08 val_old;
		byte_tt dual;
		byte_tt found;
		byte_tt lost;
	} edge_b08_type;

	typedef struct
	{
		uu16 val_old;
		word_tt dual;
		word_tt found;
		word_tt lost;
	} edge_b16_type;

	typedef struct
	{
		uu32 val_old;
		dword_tt dual;
		dword_tt found;
		dword_tt lost;
	} edge_b32_type;

// 异步创建边沿时，需要在主循环清除边沿状态
#define edge_clr(obj, val_now) \
	do                         \
	{                          \
		obj.dual.uval = 0;     \
		obj.found.uval = 0;    \
		obj.lost.uval = 0;     \
	} while (0)

#define edge_gen(obj, val_now)                       \
	do                                               \
	{                                                \
		obj.dual.uval = (val_now) ^ obj.val_old;     \
		obj.found.uval = obj.dual.uval & (val_now);  \
		obj.lost.uval = obj.dual.uval & obj.val_old; \
		obj.val_old = val_now;                       \
	} while (0)

/*****************************************************************************
 * @brief   预分频定时器定义
 *****************************************************************************/
typedef struct {
	uint16_t div;
	uint16_t val;
} div_time_16_type;

/*****************************************************************************
 * @brief   EOF
 *****************************************************************************/
#ifdef __cplusplus
}
#endif

#endif /* _MY_MICRO_FUN_H_ */
